package com.qianxx.viewlibrary.chart.statistical;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.qianxx.viewlibrary.R;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * 水平数据统计面板
 */
public class HorizotalStatisticalPanel extends View implements Animator.AnimatorListener,Runnable {
    //画笔
    private Paint paint;
    //柱状条景色
    private int columnarColor = Color.WHITE;
    //控件宽度
    private int width;
    //控件高度
    private int height;
    //当前进度的百分比
    private double percent;
    //动画持续时间
    private long duration = 1800;
    //最大数值
    private double maxValue;
    //字体颜色
    private int textColor = Color.BLACK;
    //字体大小
    private float textSize = 26;
    //文字与柱状条的间距
    private float textMargin = 5;
    //保留2位小数
    private DecimalFormat decimalFormat = new DecimalFormat("0.00");
    //点击监听器
    private OnItemClickListener listener;
    //被选中的柱状条的位置
    private int position;

    //用来记录所有柱状条的矩形坐标
    List<RectF> points = new ArrayList<>();

    //数据集
    private List<Double> list = new ArrayList<>();

    public List<Double> getList() {
        return list;
    }

    public void setList(List<Double> list) {
        this.list = list;
        this.position = list.size() - 1;
        startAnimation();
        post(this);
    }

    public HorizotalStatisticalPanel(Context context) {
        this(context, null);
    }

    public HorizotalStatisticalPanel(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public HorizotalStatisticalPanel(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.StatisticalBar);
        columnarColor = ta.getColor(R.styleable.StatisticalBar_columnar_Color, Color.WHITE);
        textSize = ta.getDimension(R.styleable.StatisticalBar_text_Size, 26);
        textColor = ta.getColor(R.styleable.StatisticalBar_text_Color, Color.BLACK);
        ta.recycle();

        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTextSize(textSize);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = MeasureSpec.getSize(widthMeasureSpec);
        height = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        try {
            //绘制背景柱状条
            drawBackground(canvas);
            //绘制前景柱状条
            drawForeground(canvas);
            //绘制文字
            drawText(canvas);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 绘制背景柱状条
     *
     * @param canvas
     */
    private void drawBackground(Canvas canvas) {
        paint.setColor(columnarColor);
        paint.setAlpha(80);

        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == null)
                continue;

            float left = 0;
            float top = (height - getTextHeight("￥") * list.size()) / (list.size() + 1) * (i + 1) + getTextHeight("￥") * i;
            float right = width;
            float bottom = top + getTextHeight("￥") + textMargin * 2;

            RectF background = new RectF();
            background.left = left;
            background.top = top;
            background.right = right;
            background.bottom = bottom;
            canvas.drawRoundRect(background, 45, 45, paint);
        }
    }

    /**
     * 绘制前景柱状条
     *
     * @param canvas
     */
    private void drawForeground(Canvas canvas) {
        paint.setColor(columnarColor);

        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == null)
                continue;

            //被选中的柱状条，颜色较深
            paint.setAlpha(i == position ? 255 : 150);

            float left = 0;
            float top = (height - getTextHeight("￥") * list.size()) / (list.size() + 1) * (i + 1) + getTextHeight("￥") * i;
            float right = (float) (width * list.get(i) / maxValue * percent);
            float bottom = top + getTextHeight("￥") + textMargin * 2;

            RectF background = new RectF();
            background.left = left;
            background.top = top;
            background.right = right;
            background.bottom = bottom;
            canvas.drawRoundRect(background, 45, 45, paint);
        }
    }

    /**
     * 绘制文字
     *
     * @param canvas
     */
    private void drawText(Canvas canvas) {
        paint.setColor(textColor);
        paint.setAlpha(255);
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == null)
                continue;

            String text = "￥" + twodecimalPlaces(list.get(i) * percent + "");
            float x = (float) (width * list.get(i) / maxValue * percent) - (getTextWidth(text) + textMargin * 2);
            float y = (height - getTextHeight("￥") * list.size()) / (list.size() + 1) * (i + 1) + getTextHeight("￥") * i
                    + (getTextHeight("￥") + textMargin);

            float indicatorWidth = (float) (width * list.get(i) / maxValue * percent);
            x = getTextWidth(text) >= indicatorWidth ? (indicatorWidth + 2 * textMargin) : x;

            canvas.drawText(text, x, y, paint);
        }
    }

    /**
     * 获取文本的宽度
     *
     * @return
     */
    private int getTextWidth(String text) {
        Rect rect = new Rect();
        paint.setTextSize(textSize);
        paint.getTextBounds(text, 0, text.length(), rect);
        return rect.width();
    }

    /**
     * 获取文本的高度
     *
     * @return
     */
    private int getTextHeight(String text) {
        Rect rect = new Rect();
        paint.setTextSize(textSize);
        paint.getTextBounds(text, 0, text.length(), rect);
        return rect.height();
    }

    /**
     * 设置最大进度值
     *
     * @param maxValue
     */
    public void setMaxValue(double maxValue) {
        this.maxValue = maxValue;
    }


    /**
     * 保留2位小数
     *
     * @param number
     * @return
     */
    public String twodecimalPlaces(String number) {
        return decimalFormat.format(Double.parseDouble(number));
    }

    /**
     * 开始执行动画
     */
    private void startAnimation() {
        setLayerType(LAYER_TYPE_HARDWARE, null);

        ObjectAnimator an = ObjectAnimator.ofFloat(this, "percent", 0, 1);
        an.setInterpolator(new FastOutSlowInInterpolator());
        an.addListener(this);
        an.setDuration(duration);
        an.start();
    }

    public double getPercent() {
        return percent;
    }

    public void setPercent(float percent) {
        this.percent = percent;
        invalidate();
    }

    /**
     * 记录每个柱状条的矩形坐标
     */
    private void recodePoint() {
        points.clear();
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == null)
                continue;

            float left = 0;
            float top = (height - getTextHeight("￥") * list.size()) / (list.size() + 1) * (i + 1) + getTextHeight("￥") * i;
            float right = width;
            float bottom = top + getTextHeight("￥") + textMargin * 2;

            RectF background = new RectF();
            background.left = left;
            background.top = top;
            background.right = right;
            background.bottom = bottom;

            points.add(background);
        }
    }

    @Override
    public void onAnimationStart(Animator animation) {

    }

    @Override
    public void onAnimationEnd(Animator animation) {
        setLayerType(LAYER_TYPE_NONE, null);
    }

    @Override
    public void onAnimationCancel(Animator animation) {

    }

    @Override
    public void onAnimationRepeat(Animator animation) {

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                for (int i = 0; i < points.size(); i++) {
                    if ((event.getX() >= points.get(i).left && event.getX() <= points.get(i).right)
                            && (event.getY() >= points.get(i).top && event.getY() <= points.get(i).bottom)) {
                        if (listener != null)
                            listener.onItemClick(i, list.get(i));
                        position = i;
                        invalidate();
                    }
                }
                break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    public void run() {
        recodePoint();
    }

    public interface OnItemClickListener {
        void onItemClick(int position, double value);
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        this.listener = listener;
    }
}
